package main

import (
	"github.com/sirupsen/logrus"
	"sync"
	"time"
)

type ThreadSafeSet struct {
	sync.RWMutex
	s []int
}

func (set *ThreadSafeSet) Iter() <-chan interface{} {
	ch := make(chan interface{}, 100)
	go func() {
		set.RLock()
		for elem := range set.s {
			ch <- elem
			logrus.Println("put:", elem, ",")
			time.Sleep(2 * time.Millisecond)
		}
		close(ch)
		set.RUnlock()
	}()
	return ch
}

// 正常
func read() {
	set := ThreadSafeSet{}
	set.s = make([]int, 100)
	ch := set.Iter()
	closed := false
	for {
		select {
		case v, ok := <-ch:
			if ok {
				logrus.Println("get:", v, ",")
				time.Sleep(100 * time.Millisecond)
			} else {
				closed = true
			}
		}
		if closed {
			logrus.Println("closed")
			break
		}

	}
	logrus.Println("Done")
}

// 有问题
// 内部迭代出现阻塞。默认初始化时无缓冲区，需要等待接收者读取后才能继续写入。
func unRead() {
	set := ThreadSafeSet{}
	set.s = make([]int, 100)
	ch := set.Iter()
	//_ = ch
	//time.Sleep(5 * time.Second)
	//fmt.Print("Done")

	for{
		select {
		case res, ok := <-ch:
			if !ok {
				logrus.Println(res)
				return
			}
		}
	}

	// break标签 退出循环
	/*forEnd:
	for{
		select {
		case res, ok := <-ch:
			if !ok {
				logrus.Println(res)
				//return
				break forEnd
			}
		}

	}*/

	// goto
	/*for {
		select {
		case res, ok := <-ch:
			if !ok {
				logrus.Println(res)
				goto forEnd
			}
		}
	}
forEnd:*/
}
func main() {
	//read()
	unRead()
}
